#include "CommandHandler.h"

#include "MultimodalTestApp.h"

#include "VoiceRecognizer.h"
#include "Speaker.h"
#include "NetListener.h"


DWORD WINAPI NetListenerThread(LPVOID lpParameter); //DO NOT MOVE those declarations outside the CPP! Will not work!
DWORD WINAPI VoiceRecognizerThread(LPVOID lpParameter);

	CommandHandler::CommandHandler(MultimodalTestApp *app){

	m_world = app->getWorld();
	speaker = new Speaker();
	
	//Initialize game values
	actionFromListener=NONE;
	gameStateFromListener=RUNNING;
	physicsElementFromListener[0]=6;
	physicsElementFromListener[1]=0.95;
	physicsElementFromListener[2]=0.83;
	actionFromApp=NONE;
	gameStateFromApp=NONE;

	if(useVoiceRecognizer)
		startVoiceRecognizer();
	if(useNetListener)
		startNetListener();
	//if(useVoiceRecognizer)
	//WaitForSingleObject(voiceRecognizerHandle, INFINITE); // wait for thread to exit
	//if(useNetListener)
	//WaitForSingleObject(netListenerHandle, INFINITE); // wait for thread to exit
}

void CommandHandler::startNetListener(void){
	DWORD netListenerId;
	netListener = new NetListener(this);

	HANDLE netListenerHandle = CreateThread( NULL, 0, NetListenerThread, this, 0L, &netListenerId);
	//netListenerHandle = CreateThread( NULL, 0, NetListenerThread, this, 0L, &netListenerId);

	//WaitForSingleObject(netListenerHandle, INFINITE); // wait for thread to exit
}

void CommandHandler::startVoiceRecognizer(void){
	DWORD voiceRecognizerId;
	voiceRecognizer = new VoiceRecognizer(this);

	HANDLE voiceRecognizerHandle= CreateThread( NULL, 0, VoiceRecognizerThread, this, 0L, &voiceRecognizerId);
	//voiceRecognizerHandle= CreateThread( NULL, 0, VoiceRecognizerThread, this, 0L, &voiceRecognizerId);
	//Do not use this --> //WaitForSingleObject(voiceRecognizerHandle, INFINITE); // wait for thread to exit
}

CommandHandler::~CommandHandler(void){}

void CommandHandler::setGameState(bool fromApp, int gameState){
	if(fromApp)
		this->gameStateFromApp=gameState;
	else
		this->gameStateFromListener=gameState;
}

int CommandHandler::getGameState(bool fromApp){
	if(fromApp)
	return gameStateFromApp;
	else
	return gameStateFromListener;
}
	
void CommandHandler::setAction(bool fromApp, int action){
	if(fromApp)
	this->actionFromApp=action;
	else
	this->actionFromListener=action;
}

int CommandHandler::getAction(bool fromApp){
	if(fromApp)
		return actionFromApp;
	else
		return actionFromListener;
}

void CommandHandler::setPhysics(bool fromApp, int physicsElement, float physicsValue)
{
	if(fromApp)
		;//N/A
	else{
		physicsElementFromListener[physicsElement]=physicsValue;
	}
}

float CommandHandler::getPhysics(bool fromApp, int physicsElement)
{
	if(fromApp)
		;//N/A
	else
		return physicsElementFromListener[physicsElement];
}

void CommandHandler::setHandPosition(Ogre::Vector2 handPosition)
{
	app->setHandPosition(handPosition);
}

Ogre::Vector2 CommandHandler::getHandPosition(void)
{
	return app->getHandPosition();
}

//Separately running thread listening to incoming network traffic
DWORD WINAPI NetListenerThread(LPVOID lpParameter)
{
	CommandHandler *commandHandler = (CommandHandler*) lpParameter;
    commandHandler->getNetListener()->startListening();
	return 0;
}

//Separately running thread listening for voice commands
DWORD WINAPI VoiceRecognizerThread(LPVOID lpParameter)
{
	CommandHandler *commandHandler = (CommandHandler*) lpParameter;
	commandHandler->getVoiceRecognizer()->listen(true);
	return 0;
}